package com.dc.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dc.common.ResponseResultVO;
import com.dc.entity.ro.DeviceRO;
import com.dc.entity.vo.CadDataAnalysis;
import com.dc.entity.vo.FeaturesVO;
import com.dc.entity.vo.GeometryVO;
import com.dc.feign.DeviceApiServiceFeign;
import com.dc.mapper.DeviceMapper;
import com.dc.model.Device;
import com.dc.service.DeviceService;
import com.dc.util.Base64DecodeMultipartFile;
import com.dc.util.ExportUtil;
import com.dc.util.SnowflakeIdWorker;
import com.dc.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.dc.common.ResponseResultVO.checkParameterIsNotNull;
import static com.dc.common.ResponseResultVO.successResult;

@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {

    @Resource
    private DeviceMapper deviceMapper;
    @Resource
    private DeviceService deviceService;
    @Resource
    private DeviceApiServiceFeign deviceApiServiceFeign;


    @Override
    public ResponseResultVO insertDevice(DeviceRO ro) {
        Device device = new Device();
        BeanUtils.copyProperties(ro, device);
        device.setId(SnowflakeIdWorker.generateId());
        return ResponseResultVO.insertResult(deviceMapper.insert(device));
    }

    @Override
    public ResponseResultVO updateDevice(DeviceRO ro) {
        checkParameterIsNotNull(String.valueOf(ro.getId()), "id不能为空");
        Device device = new Device();
        device.setId(ro.getId());
        device.setDeviceFactory(ro.getDeviceFactory());
        device.setDeviceAddress(ro.getDeviceAddress());
        device.setModel(ro.getModel());
        device.setName(ro.getName());
        device.setSubSystem(ro.getSubSystem());
        return ResponseResultVO.updateResult(deviceMapper.updateById(device));
    }

    @Override
    public ResponseResultVO replaceDevice(DeviceRO ro) {
        checkParameterIsNotNull(String.valueOf(ro.getId()), "id不能为空");
        Device device = new Device();
        BeanUtils.copyProperties(ro, device);
        return ResponseResultVO.updateResult(deviceMapper.updateById(device));
    }

    @Override
    public ResponseResultVO deleteDevice(String ids) {
        checkParameterIsNotNull(ids, "id不能为空");
        List<String> idList = Arrays.asList(ids.split(","));
        return ResponseResultVO.deleteResult(deviceMapper.deleteBatchIds(idList));
    }

    @Override
    public ResponseResultVO selectDeviceByPage(DeviceRO ro) {
        Page page = new Page<Map<String, Object>>(ro.getCurrentPage(), ro.getPageSize());
        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(CollectionUtils.isNotEmpty(ro.getIds()), Device::getId, ro.getIds());
        queryWrapper.lambda().like(StringUtils.isNotBlank(ro.getDeviceAddress()), Device::getDeviceAddress, ro.getDeviceAddress());
        queryWrapper.lambda().eq(StringUtils.isNotBlank(ro.getSerialNumber()), Device::getSerialNumber, ro.getSerialNumber());
        queryWrapper.lambda().like(StringUtils.isNotBlank(ro.getDeviceFactory()), Device::getDeviceFactory, ro.getDeviceFactory());
        queryWrapper.lambda().eq(null != ro.getDeviceStatus(), Device::getDeviceStatus, ro.getDeviceStatus());
        queryWrapper.lambda().eq(null != ro.getSubSystem(), Device::getSubSystem, ro.getSubSystem());

        queryWrapper.lambda().eq(StringUtils.isNotBlank(ro.getFloorCode()), Device::getFloorCode, ro.getFloorCode());
        queryWrapper.lambda().eq(StringUtils.isNotBlank(ro.getDeviceType()), Device::getDeviceType, ro.getDeviceType());
        queryWrapper.lambda().ge(StringUtils.isNotBlank(ro.getAlarmTimeStart()), Device::getAlarmTime, ro.getAlarmTimeStart());
        queryWrapper.lambda().le(StringUtils.isNotBlank(ro.getAlarmTimeEnd()), Device::getAlarmTime, ro.getAlarmTimeEnd());

        queryWrapper.lambda().ge(StringUtils.isNotBlank(ro.getStartTime()), Device::getCreateTime, ro.getStartTime());
        queryWrapper.lambda().le(StringUtils.isNotBlank(ro.getEndTime()), Device::getCreateTime, ro.getEndTime());

        if (StringUtils.isNotBlank(ro.getSearchValue())) {
            queryWrapper.lambda().and(wap -> {
                wap.apply("1=1");
                wap.like(Device::getName, ro.getSearchValue()).or()
                        .like(Device::getSerialNumber, ro.getSearchValue()).or()
                        .like(Device::getDeviceFactory, ro.getSearchValue());
            });
        }

        queryWrapper.lambda().orderByDesc(Device::getUpdateTime);
        return ResponseResultVO.resultList(deviceMapper.selectPage(page, queryWrapper), ro);
    }

    @Override
    public void deviceRecordExport(HttpServletResponse response, DeviceRO ro) {
        ResponseResultVO roadReportForm = this.selectDeviceByPage(ro);
        HashMap<String, Object> data = (HashMap<String, Object>) roadReportForm.getData();
        ExportUtil.exportExcelNew("设备记录", (List) data.get("list"), Device.class, response);
    }

    @Override
    public void exportDeviceRecordModel(HttpServletResponse response) {
        ExportUtil.downloadExcel(response, "device.xls", "设备记录模板下载");
    }

    @Override
    public ResponseResultVO importDeviceRecord(MultipartFile file) {
        try {
            ImportParams params = new ImportParams();
            List<Device> result = ExcelImportUtil.importExcel(file.getInputStream(), Device.class, params);
            for (Device dto : result) {
                dto.setId(SnowflakeIdWorker.generateId());

            }
            deviceService.saveBatch(result);
            return ResponseResultVO.successResult("成功");
        } catch (Exception exception) {
            exception.printStackTrace();
            return ResponseResultVO.failResult("失败");
        }
    }

    @Override
    public ResponseResultVO fileContentReading(MultipartFile multipartFile) {
        String s = Base64DecodeMultipartFile.fileContentReading(multipartFile);
        CadDataAnalysis cadDataAnalysis = JSON.parseObject(s, CadDataAnalysis.class);
        List<FeaturesVO> features = cadDataAnalysis.getFeatures();
        for (FeaturesVO vo : features) {
            GeometryVO geometry = vo.getGeometry();
            List<String> coordinates = geometry.getCoordinates();
            BigDecimal bigDecimal = new BigDecimal(coordinates.size());
            BigDecimal xSum = new BigDecimal(0);
            BigDecimal ySum = new BigDecimal(0);
            for (String xy : coordinates) {
                String replace = xy.replace("[", "");
                String[] split = replace.split(",");
                BigDecimal x = new BigDecimal(split[0]);
                BigDecimal y = new BigDecimal(split[1]);
                xSum = xSum.add(x);
                ySum = ySum.add(y);
            }
            BigDecimal xDivide = xSum.divide(bigDecimal, 15, BigDecimal.ROUND_HALF_UP);  //X轴数据
            BigDecimal yDivide = ySum.divide(bigDecimal, 15, BigDecimal.ROUND_HALF_UP);  //Y轴数据
            System.out.println(xDivide);
            System.out.println(yDivide);
        }
        return successResult(cadDataAnalysis);
    }

    /**
     * 设备类型
     *
     * @return
     */
    @Override
    public ResponseResultVO getDeviceType() {
        Set<Map<String, Object>> list = new HashSet<>();
        deviceService.list().stream()
                .filter(cc -> (null != cc.getDeviceType() && StringUtils.isNotBlank(cc.getDeviceType())))
                .collect(Collectors.toList()).forEach(cc -> {
            Map<String, Object> resultMap = new HashMap<>(2);
            resultMap.put("id", cc.getSerialNumber());
            resultMap.put("name", cc.getName());
            list.add(resultMap);
        });

        ////////////////////////////////////// 测试数据
        Map<String, Object> resultMap = new HashMap<>(2);
        resultMap.put("id", 0);
        resultMap.put("name", "联动");
        list.add(resultMap);

        resultMap = new HashMap<>(2);
        resultMap.put("id", 1);
        resultMap.put("name", "防火门");
        list.add(resultMap);

        resultMap = new HashMap<>(2);
        resultMap.put("id", 2);
        resultMap.put("name", "安防探头");
        list.add(resultMap);

        resultMap = new HashMap<>(2);
        resultMap.put("id", 3);
        resultMap.put("name", "喷淋系统");
        list.add(resultMap);

        resultMap = new HashMap<>(2);
        resultMap.put("id", 4);
        resultMap.put("name", "气体灭火器");
        list.add(resultMap);

        resultMap = new HashMap<>(2);
        resultMap.put("id", 5);
        resultMap.put("name", "干粉灭火器");
        list.add(resultMap);

        resultMap = new HashMap<>(2);
        resultMap.put("id", 6);
        resultMap.put("name", "余压监控");
        list.add(resultMap);

        resultMap = new HashMap<>(2);
        resultMap.put("id", 7);
        resultMap.put("name", "应急照明灯");
        list.add(resultMap);

        return ResponseResultVO.successResult(list);
    }

    /**
     * 分页显示 摄像机列表数据
     *
     * @param page
     * @return
     */
    @Override
    public ResponseResultVO getDeviceInfo(int page) {
        String info = deviceApiServiceFeign.getDeviceInfo(page);
        // null 替换
        JSONObject all = JSONUtil.parseObj(info.replaceAll("null", "\"\""));
        return ResponseResultVO.successResult(all);
    }

    /**
     * 根据设备 编码 查看摄像机实时情况
     *
     * @param deviceCode
     * @return
     */
    @Override
    public ResponseResultVO getGetVideoRealtime(String deviceCode) {
        return ResponseResultVO.successResult(JSONUtil.parseObj(deviceApiServiceFeign.getGetVideoRealtime(deviceCode)));
    }

    /**
     * 查看历史回访片段
     *
     * @param deviceCode
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public ResponseResultVO getDeviceHistory(String deviceCode, String startTime, String endTime) {
        return ResponseResultVO.successResult(JSONUtil.parseObj(deviceApiServiceFeign.getDeviceHistory(deviceCode, startTime, endTime)));
    }
}
